bitkeeper revision 1.1310 (4263d01alGeX35dYhvzi6Uo_ZNlWkQ)
authormaf46@burn.cl.cam.ac.uk <maf46@burn.cl.cam.ac.uk>
Mon, 18 Apr 2005 15:19:54 +0000 (15:19 +0000)
committermaf46@burn.cl.cam.ac.uk <maf46@burn.cl.cam.ac.uk>
Mon, 18 Apr 2005 15:19:54 +0000 (15:19 +0000)
Fix bug with get_page_type where validating an L2/L3/L4 page which contained a self
reference would cause xen to busy-wait forever.

Signed-off-by: michael.fetterman@cl.cam.ac.uk
xen/arch/x86/mm.c

index 1a0a9f95120887bd439cd1d432e38b89d349e829..48acad9e999ac6d50e4ea01c6316664a0297cd38 100644 (file)
@@ -1229,35 +1229,38 @@ int get_page_type(struct pfn_info *page, u32 type)
                     nx |= PGT_validated;
             }
         }
-        else if ( unlikely(!(x & PGT_validated)) )
-        {
-            /* Someone else is updating validation of this page. Wait... */
-            while ( (y = page->u.inuse.type_info) == x )
-                cpu_relax();
-            goto again;
-        }
-        else if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) )
+        else
         {
-            if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
-            {
-                if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
-                     ((type & PGT_type_mask) != PGT_l1_page_table) )
-                    MEM_LOG("Bad type (saw %08x != exp %08x) for pfn %p",
-                            x, type, page_to_pfn(page));
-                return 0;
-            }
-            else if ( (x & PGT_va_mask) == PGT_va_mutable )
+            if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) )
             {
-                /* The va backpointer is mutable, hence we update it. */
-                nx &= ~PGT_va_mask;
-                nx |= type; /* we know the actual type is correct */
+                if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
+                {
+                    if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
+                         ((type & PGT_type_mask) != PGT_l1_page_table) )
+                        MEM_LOG("Bad type (saw %08x != exp %08x) for pfn %p",
+                                x, type, page_to_pfn(page));
+                    return 0;
+                }
+                else if ( (x & PGT_va_mask) == PGT_va_mutable )
+                {
+                    /* The va backpointer is mutable, hence we update it. */
+                    nx &= ~PGT_va_mask;
+                    nx |= type; /* we know the actual type is correct */
+                }
+                else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
+                          ((type & PGT_va_mask) != (x & PGT_va_mask)) )
+                {
+                    /* This table is potentially mapped at multiple locations. */
+                    nx &= ~PGT_va_mask;
+                    nx |= PGT_va_unknown;
+                }
             }
-            else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
-                      ((type & PGT_va_mask) != (x & PGT_va_mask)) )
+            if ( unlikely(!(x & PGT_validated)) )
             {
-                /* This table is potentially mapped at multiple locations. */
-                nx &= ~PGT_va_mask;
-                nx |= PGT_va_unknown;
+                /* Someone else is updating validation of this page. Wait... */
+                while ( (y = page->u.inuse.type_info) == x )
+                    cpu_relax();
+                goto again;
             }
         }
     }